package com.wei.czz.framework.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.common.vo.common.UpdateStatusVo;
import com.wei.czz.common.vo.store.StoreAccountVo;
import com.wei.czz.framework.store.dao.StoreAccountDao;
import com.wei.czz.framework.store.entity.StoreAccountEntity;
import com.wei.czz.framework.store.service.StoreAccountService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


import java.util.*;


@Service("storeAccountService")
@AllArgsConstructor
public class StoreAccountServiceImpl extends ServiceImpl<StoreAccountDao, StoreAccountEntity> implements StoreAccountService {

    private static final Logger log = LoggerFactory.getLogger(StoreAccountServiceImpl.class);
    @Override
    public Long saveStoreAccount(StoreAccountVo storeAccountVo) {
        Long id = storeAccountVo.getId();
        if (Objects.nonNull(id)) {
            // 修改
            StoreAccountEntity storeAccount = baseMapper.selectById(id);
            if (Objects.isNull(storeAccount)) {
                throw new RuntimeException("商店账户不存在");
            }
            // 属性赋值
            this.buildStoreAccount(storeAccountVo, storeAccount);

            int count = baseMapper.updateById(storeAccount);
            log.info("修改商店账户完成。count={}", count);
        } else {
            // 添加
            StoreAccountEntity storeAccount = this.buildStoreAccount(storeAccountVo, null);
            int count = baseMapper.insert(storeAccount);
            log.info("添加商店账户完成。count={}", count);
            id = storeAccount.getId();
        }
        return id;
    }

    @Override
    public Long saveStoreAccount(StoreAccountEntity storeAccount) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        storeAccount.setId(null)
                .setStatus(CommonEnum.ZERO.getValue())
                .setDefaultStatus(CommonEnum.ZERO.getValue())
                .setDeleteStatus(CommonEnum.ZERO.getValue())
                .setUpdateUser(StringUtils.EMPTY)
                .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                .setCreateTime(date)
                .setCreateUser(userPo.getUsername())
                .setCreateUserId(userPo.getUserId());
        int count = baseMapper.insert(storeAccount);
        log.info("添加商店账户完成.count={}", count);
        return storeAccount.getId();
    }

    @Transactional
    @Override
    public void copyStoreAccount(Long preStoreId, Long storeId) {
        log.info("开始复制商店账户。preStoreId={} storeId={}", preStoreId, storeId);

        LambdaQueryWrapper<StoreAccountEntity> storeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeAccountLambdaQueryWrapper.eq(StoreAccountEntity::getStoreId, preStoreId)
                .eq(StoreAccountEntity::getDefaultStatus, CommonEnum.ONE.getValue())
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO);
        // 查询
        List<StoreAccountEntity> storeAccountList = baseMapper.selectList(storeAccountLambdaQueryWrapper);
        if (storeAccountList.isEmpty()) {
            log.info("可复制商店账户为空");
            return;
        }
        Date date = new Date();

        for (StoreAccountEntity storeAccount : storeAccountList) {
            storeAccount.setId(null)
                    .setStoreId(storeId)
                    .setUpdateTime(date)
                    .setUpdateUser(StringUtils.EMPTY)
                    .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                    .setCreateTime(date);
        }
        // 批量新增
        boolean bool = this.saveBatch(storeAccountList);

        log.info("复制商店账户完成。bool={}", bool);
    }

    @Override
    public List<StoreAccountEntity> getStoreDefaultAccountList(List<Long> storeIdList) {

        LambdaQueryWrapper<StoreAccountEntity> storeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 匹配条件
        storeAccountLambdaQueryWrapper.in(StoreAccountEntity::getStoreId, storeIdList)
                .eq(StoreAccountEntity::getDefaultStatus, CommonEnum.ZERO.getValue())
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<StoreAccountEntity> storeAccountList = baseMapper.selectList(storeAccountLambdaQueryWrapper);
        log.info("商店默认账户查询完成。size={}", storeAccountList.size());
        return storeAccountList;
    }

    @Override
    public StoreAccountEntity getStoreDefaultAccount(Long storeId) {

        LambdaQueryWrapper<StoreAccountEntity> storeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 匹配条件
        storeAccountLambdaQueryWrapper.eq(StoreAccountEntity::getStoreId, storeId)
                .eq(StoreAccountEntity::getDefaultStatus, CommonEnum.ZERO.getValue())
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        storeAccountLambdaQueryWrapper.last(" limit 1");
        // 查询
        List<StoreAccountEntity> storeAccountList = baseMapper.selectList(storeAccountLambdaQueryWrapper);
        log.info("查询商店默认账户完成。size={}", storeAccountList.size());
        if (storeAccountList.isEmpty()) {
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "商店账户不存在");
        }
        return storeAccountList.get(0);
    }

    @Override
    public List<StoreAccountEntity> getStoreAccountList(Long storeId) {

        LambdaQueryWrapper<StoreAccountEntity> storeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 匹配条件
        storeAccountLambdaQueryWrapper.eq(StoreAccountEntity::getStoreId, storeId)
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<StoreAccountEntity> storeAccountList = baseMapper.selectList(storeAccountLambdaQueryWrapper);
        if (storeAccountList.isEmpty()) {
            log.info("查询商店账户结果为空。storeId={}", storeId);
        }
        storeAccountList.sort(Comparator.comparing(StoreAccountEntity::getSort));
        return storeAccountList;
    }

    @Override
    public Integer getNextSort(Long storeId) {
        Integer maxSort = baseMapper.selectMaxSort(storeId, CommonEnum.ZERO.getValue());
        if (Objects.isNull(maxSort)) {
            maxSort = 0;
        }
        return maxSort + 1;
    }

    @Override
    public StoreAccountEntity getStoreAuditAccount(Long storeId) {
        if (Objects.isNull(storeId)) {
            log.info("传入的商店主键为空");
            return null;
        }
        LambdaQueryWrapper<StoreAccountEntity> storeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeAccountLambdaQueryWrapper.eq(StoreAccountEntity::getStoreId, storeId)
                .eq(StoreAccountEntity::getAuditStatus, CommonEnum.ZERO.getValue())
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        storeAccountLambdaQueryWrapper.last(" limit 1");
        // 查询
        List<StoreAccountEntity> storeAccountList = baseMapper.selectList(storeAccountLambdaQueryWrapper);
        if (storeAccountList.isEmpty()) {
            log.info("查询商店正在审核中的账户结果为空。storeId={}", storeId);
            return null;
        }
        return storeAccountList.get(0);
    }

    @Override
    public List<StoreAccountEntity> batchGetStoreAuditAccount(Collection<Long> storeIdCollection,
                                                              Integer deleteStatus) {
        if (CollectionUtils.isEmpty(storeIdCollection)) {
            log.info("传入的商店主键集合为空");
            return Collections.emptyList();
        }
        LambdaQueryWrapper<StoreAccountEntity> storeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeAccountLambdaQueryWrapper.in(StoreAccountEntity::getStoreId, storeIdCollection)
                .eq(StoreAccountEntity::getAuditStatus, CommonEnum.ZERO.getValue())
                .eq(Objects.nonNull(deleteStatus), StoreAccountEntity::getDeleteStatus, deleteStatus);
        // 查询
        List<StoreAccountEntity> storeAccountList = baseMapper.selectList(storeAccountLambdaQueryWrapper);
        if (storeAccountList.isEmpty()) {
            log.info("批量查询商店正在审核中的账户结果为空。storeIdCollection={} deleteStatus={}", storeIdCollection,
                    deleteStatus);
        }
        return storeAccountList;
    }

    @Override
    public StoreAccountEntity getStoreAccount(Long id) {
        StoreAccountEntity storeAccount = baseMapper.selectById(id);
        if (Objects.isNull(storeAccount)) {
            log.info("商店账户不存在。id={}", id);
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "商店账户不存在");
        }
        if (CommonEnum.ONE.getValue().equals(storeAccount.getDeleteStatus())) {
            log.info("商店账户已删除。id={}", id);
            throw new CzzException(ResultEnum.REFRESH.getCode(), "商店账户不存在");
        }
        return storeAccount;
    }

    @Override
    public void updateStoreAccount(StoreAccountEntity storeAccount) {
        if (Objects.isNull(storeAccount.getId())) {
            log.info("传入的账户主键为空。{}", storeAccount);
            throw new CzzException();
        }
        int count = baseMapper.updateById(storeAccount);
        log.info("修改商店账户完成。count={}", count);
    }

    @Override
    public void updateStoreAccountStatus(UpdateStatusVo updateStatusVo) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        LambdaUpdateWrapper<StoreAccountEntity> storeAccountLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        storeAccountLambdaUpdateWrapper.set(StoreAccountEntity::getStatus, updateStatusVo.getStatus())
                .set(StoreAccountEntity::getUpdateTime, date)
                .set(StoreAccountEntity::getUpdateUser, userPo.getUsername())
                .set(StoreAccountEntity::getUpdateUserId, userPo.getUserId());
        storeAccountLambdaUpdateWrapper.in(StoreAccountEntity::getId, updateStatusVo.getIdList())
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 更新
        int count = baseMapper.update(null, storeAccountLambdaUpdateWrapper);
        log.info("修改商店账户状态完成。count={}", count);
    }

    @Override
    public void deleteStoreAccount(Long id) {
        // 获取正在删除商店账户的用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        LambdaUpdateWrapper<StoreAccountEntity> storeAccountLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        storeAccountLambdaUpdateWrapper.set(StoreAccountEntity::getDeleteStatus, CommonEnum.ONE.getValue())
                .set(StoreAccountEntity::getUpdateTime, date)
                .set(StoreAccountEntity::getUpdateUser, userPo.getUsername())
                .set(StoreAccountEntity::getUpdateUserId, userPo.getUserId());
        storeAccountLambdaUpdateWrapper.eq(StoreAccountEntity::getId, id)
                .eq(StoreAccountEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 删除
        int count = baseMapper.update(null, storeAccountLambdaUpdateWrapper);
        log.info("删除商店账户完成。count={}", count);
    }

    /**
     * 生成商店账号对象
     * @param storeAccountVo 参数对象
     * @param storeAccount   商店账号对象
     * @return 商店账号对象
     */
    private StoreAccountEntity buildStoreAccount(StoreAccountVo storeAccountVo, StoreAccountEntity storeAccount) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();
        boolean isUpdate = Objects.nonNull(storeAccount);

        if (!isUpdate) {
            storeAccount = new StoreAccountEntity();
        }
        storeAccount.setStoreId(storeAccountVo.getStoreId())
                .setType(Optional.ofNullable(storeAccountVo.getType()).orElse(CommonEnum.MINUS_ONE.getValue()))
                .setName(Optional.ofNullable(storeAccountVo.getName()).orElse(StringUtils.EMPTY))
                .setIdCard(Optional.ofNullable(storeAccountVo.getIdCard()).orElse(StringUtils.EMPTY))
                .setEnterpriseName(Optional.ofNullable(storeAccountVo.getEnterpriseName()).orElse(StringUtils.EMPTY))
                .setEnterpriseNo(Optional.ofNullable(storeAccountVo.getEnterpriseNo()).orElse(StringUtils.EMPTY))
                .setBankNo(Optional.ofNullable(storeAccountVo.getBankNo()).orElse(StringUtils.EMPTY))
                .setBankName(Optional.ofNullable(storeAccountVo.getBankName()).orElse(StringUtils.EMPTY))
                .setBankBranchName(Optional.ofNullable(storeAccountVo.getBankBranchName()).orElse(StringUtils.EMPTY))
                .setBankMobile(Optional.ofNullable(storeAccountVo.getBankMobile()).orElse(StringUtils.EMPTY))
                .setBankCity(Optional.ofNullable(storeAccountVo.getBankCity()).orElse(CommonEnum.MINUS_ONE.getValue()))
                .setSort(Optional.ofNullable(storeAccountVo.getSort()).orElse(CommonEnum.ONE.getValue()))
                .setStatus(CommonEnum.ZERO.getValue())
                .setDefaultStatus(
                        Optional.ofNullable(storeAccountVo.getDefaultStatus())
                                .orElse(CommonEnum.ZERO.getValue())
                )
                .setAuditStatus(
                        Optional.ofNullable(storeAccountVo.getAuditStatus())
                                .orElse(CommonEnum.ONE.getValue())
                )
                .setDeleteStatus(CommonEnum.ZERO.getValue())
                .setUpdateTime(date);

        if (isUpdate) {
            storeAccount.setUpdateUser(userPo.getUsername())
                    .setUpdateUserId(userPo.getUserId());
        } else {
            storeAccount.setUpdateUser(StringUtils.EMPTY)
                    .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                    .setCreateTime(date)
                    .setCreateUser(userPo.getUsername())
                    .setCreateUserId(userPo.getUserId());
        }
        return storeAccount;
    }
}